<template>
	<view v-if="show_" ref="xt-transition" :class="classes" @tap="handleClick" :style="[mergeStyle]" @touchmove="no">
		<slot />
	</view>
</template>

<script>
	// #ifdef VUE3
	import {
		nextTick
	} from 'vue';
	// #endif
	import props from './props.js'
	export default {
		name: 'xt-transition',
		mixins: [props],
		data() {
			return {
				show_: false,
				status: '',
				display: false,
				transitionEnded: false,
				classes: ''
			};

		},
		computed: {
			mergeStyle() {
				return {
					transitionDuration: `${this.duration}ms`,
					transitionTimingFunction: this.timingFunction,
					...this.customStyle
				}
			}
		},
		methods: {
			no(e) {

			},
			getClassNames(name) {
				return {
					enter: `${name}-enter ${name}-enter-active`,
					'enter-to': `${name}-enter-to ${name}-enter-active`,
					leave: `${name}-leave ${name}-leave-active`,
					'leave-to': `${name}-leave-to ${name}-leave-active`
				}
			},
			sleep(value = 30) {
				return new Promise((resolve) => {
					setTimeout(() => {
						resolve()
					}, value)
				})
			},
			handleClick() {
				this.$emit('xtClick')
			},
			async enter() {
				const classNames = this.getClassNames(this.name)
				this.status = 'enter'
				this.show_ = true
				this.display = true
				this.classes = classNames.enter
				if (this.safeAreaTop) {
					this.classes += ' xt-popup-safe-top'
				}
				if (this.safeAreaBottom) {
					this.classes += ' xt-popup-safe-bottom'
				}
				// #ifdef VUE3
				await nextTick();
				// #endif
				// #ifdef VUE2
				await this.$nextTick();
				// #endif
				{
					await this.sleep(20)
					this.transitionEnded = false
					this.classes = classNames['enter-to']
					if (this.safeAreaTop) {
						this.classes += ' xt-popup-safe-top'
					}
					if (this.safeAreaBottom) {
						this.classes += ' xt-popup-safe-bottom'
					}
				}
			},
			// 动画离场处理
			async leave() {
				if (!this.display) return
				const classNames = this.getClassNames(this.name)
				this.status = 'leave'
				this.classes = classNames.leave
				if (this.safeAreaTop) {
					this.classes += ' xt-popup-safe-top'
				}
				if (this.safeAreaBottom) {
					this.classes += ' xt-popup-safe-bottom'
				}
				// #ifdef VUE3
				await nextTick();
				// #endif
				// #ifdef VUE2
				await this.$nextTick();
				// #endif
				{
					this.transitionEnded = false
					setTimeout(this.onTransitionEnd, this.duration)
					this.classes = classNames['leave-to']
					if (this.safeAreaTop) {
						this.classes += ' xt-popup-safe-top'
					}
					if (this.safeAreaBottom) {
						this.classes += ' xt-popup-safe-bottom'
					}
				}
			},
			// 完成过渡后触发
			onTransitionEnd() {
				if (this.transitionEnded) return
				this.transitionEnded = true
				if (!this.show && this.display) {
					this.display = false
					this.show_ = false
				}
			}
		},
		watch: {
			show: {
				handler(newVal) {
					newVal ? this.enter() : this.leave()
				},
				immediate: true
			}
		}
	}
</script>

<style scoped lang="scss">
	@import './transition.css';

	.xt-popup-safe-bottom {
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);
	}


	.xt-popup-safe-top {
		padding-top: constant(safe-area-inset-top);
		padding-top: env(safe-area-inset-top);
	}
</style>